package org.mybatis.generator.codegen.spring.jdbc.repository;

import java.util.Locale;

import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.codegen.AbstractGenerator;

public abstract class AbstractRepGenerator extends AbstractGenerator {

	public abstract void addImplementationElements(TopLevelClass topLevelClass);

	/**
	 * Convert the given name to lower case. By default, conversions will happen
	 * within the US locale.
	 * 
	 * @param name
	 *            the original name
	 * @return the converted name
	 * @since 4.2
	 */
	protected String lowerCaseName(String name) {
		return name.toLowerCase(Locale.US);
	}

	/**
	 * Convert a name in camelCase to an underscored name in lower case. Any
	 * upper case letters are converted to lower case with a preceding
	 * underscore.
	 * 
	 * @param name
	 *            the original name
	 * @return the converted name
	 * @since 4.2
	 * @see #lowerCaseName
	 */
	protected String underscoreName(String name) {
		if (name == null || name.trim().length() == 0) {
			return "";
		}
		StringBuilder result = new StringBuilder();
		result.append(lowerCaseName(name.substring(0, 1)));
		for (int i = 1; i < name.length(); i++) {
			String s = name.substring(i, i + 1);
			String slc = lowerCaseName(s);
			if (!s.equals(slc)) {
				result.append("_").append(slc);
			} else {
				result.append(s);
			}
		}
		return result.toString();
	}
	
	/**
	 * Convert a name in camelCase to an underscored name in lower case. Any
	 * upper case letters are converted to lower case with a preceding
	 * underscore.
	 * 
	 * @param name
	 *            the original name
	 * @return the converted name
	 * @since 4.2
	 * @see #lowerCaseName
	 */
	protected String toCaseName(String name) {
		if (name == null || name.trim().length() == 0) {
			return "";
		}
		name = name.toLowerCase();

		StringBuilder result = new StringBuilder(name.length());
		boolean upperCase = false;
		for (int i = 0; i < name.length(); i++) {
			char c = name.charAt(i);
			if (c == '_') {
				upperCase = true;
			} else if (upperCase) {
				result.append(Character.toUpperCase(c));
				upperCase = false;
			} else {
				result.append(c);
			}
		}

		return result.toString();
	}
	
	/**
	 * @param topLevelClass
	 */
	private void addImportedType(TopLevelClass topLevelClass) {
		topLevelClass.addImportedType(new FullyQualifiedJavaType("java.util.Map"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType("java.util.HashMap"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType(
				"org.springframework.dao.EmptyResultDataAccessException"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType(
				"org.springframework.jdbc.core.BeanPropertyRowMapper"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType(
				"org.springframework.dao.DataAccessException"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType(
				"org.springframework.jdbc.core.namedparam.MapSqlParameterSource"));
		FullyQualifiedJavaType modelClass = new FullyQualifiedJavaType(
				introspectedTable.getBaseRecordType());
		topLevelClass.addImportedType(modelClass);
	}
}
